package pl.wroc.uni.ii.evolution.servlets.databasesupport.providers;

import java.io.IOException;
import java.sql.SQLException;
import pl.wroc.uni.ii.evolution.servlets.databasesupport.structure.EvIndividualInfo;
import pl.wroc.uni.ii.evolution.servlets.databasesupport.structure.EvTaskInfo;

public interface EvDatabaseProvider{

  
  
  public void connect(String database_url,
      String database_user, String database_password) throws SQLException;
  
  
  
  public  void disconnect() throws SQLException;

  /**
   * Stores <code> individual </code> in database
   * 
   * @param individual
   * @param task_id
   * @param objective_value
   * @param cell_id
   * @param node_id
   * @return
   * @throws IOException
   */
  public int addIndividual(Object individual, long task_id,
      double objective_value, long cell_id, long node_id) throws IOException;

  /**
   * Delete individual having given <code> id </code>
   * 
   * @param id
   * @throws IOException
   */
  public boolean deleteIndividual(int id) throws IOException;

  /**
   * Delete all individuals from given task
   * 
   * @param task_id
   * @throws IOException
   */
  public void deleteIndividualsFromTask(long task_id) throws IOException;

  /**
   * Gets id's of all task in database
   * 
   */
  public Long[] getTaskIDs() throws IOException;

  /**
   * Return solution space for given cell and task
   * 
   * @param task_id
   * @param cell_id
   * @return
   * @throws IOException
   */
  public Object getSolutionSpace(long task_id, long cell_id) throws IOException;

  /**
   * Add a solution space for given task and cell to database
   * 
   * @param space
   * @param task_id
   * @param cell_id
   * @throws IOExeption
   */
  public int addSolutionSpace(long task_id, long cell_id, Object space)
      throws IOException;

  /**
   * Deletes solution spaces for given task
   * 
   * @param task_id
   * @throws IOException
   */
  public boolean deleteSolutionSpaces(long task_id) throws IOException;

  /**
   * Return information about individuals having given <code> id </code>
   * 
   * @param id
   * @param with_individual_itself
   *          if set <code> true </code> then individuals is also returned
   * @return
   * @throws IOException
   */
  public EvIndividualInfo getIndividualInfo(int id,
      boolean with_individual_itself) throws IOException;

  /**
   * Returns description of n best individuals starting from k-th. In other
   * words, returns descriptions of I_k, I_{k+1}, ..., I_{k+n-1}. The best
   * individual in the database is I_1. If there are no (k+n-1) individuals in
   * the database, the end part of the table returned is filled by nulls.
   */
  public EvIndividualInfo[] getBestIndividualInfos(long task_id, int k, int n,
      boolean with_individuals_itselves) throws IOException;

  /**
   * The same as getBestIndividualInfos, but applied only to individuals with a
   * specific creation cell.
   */
  public EvIndividualInfo[] getBestIndividualInfosMatchingCell(long task_id,
      long cell_id, int k, int n, boolean with_individuals_itselves)
      throws IOException;

  /**
   * The same as getBestIndividualInfos, but applied only to individuals with a
   * creation cell different from the specific one.
   */
  public EvIndividualInfo[] getBestIndividualInfosNotMatchingCell(long task_id,
      long cell_id, int k, int n, boolean with_individuals_itselves)
      throws IOException;

  /**
   * The same as getBestIndividualInfos, but applied only to individuals with a
   * specific node.
   */
  public EvIndividualInfo[] getBestIndividualInfosMatchingNode(long task_id,
      long node_id, int k, int n, boolean with_individuals_itselves)
      throws IOException;

  /**
   * Retruns how many individuals are stored in a database for given task
   * 
   * @param task_id
   * @return
   * @throws IOException
   */
  public int getIndividualCount(long task_id) throws IOException;

  /**
   * Returns how many individuals are stored in a database for given task,
   * created by nodes in given cell
   * 
   * @param task_id
   * @param cell_id
   * @return
   * @throws IOException
   */
  public int getIndividualCountMatchingCell(long task_id, long cell_id)
      throws IOException;

  /**
   * Returns how many individuals are stored in database for given task, created
   * by cells different than given
   * 
   * @param task_id
   * @param cell_id
   * @return
   * @throws IOException
   */
  public int getIndividualCountNotMatchingCell(long task_id, long cell_id)
      throws IOException;

  /**
   * Returns the highest interation number of solution space stored in database
   * for given task and cell
   * 
   * @param task_id
   * @param cell_id
   * @return
   * @throws IOException
   */
  public int getVersionOfNewSolutonSpace(long task_id, long cell_id)
      throws IOException;

  /**
   * Returns how many individuals are stored in database for given task, created
   * by given node
   * 
   * @param task_id
   * @param node_id
   * @return
   * @throws IOException
   */
  public int getIndividualCountMatchingNode(long task_id, long node_id)
      throws IOException;


  
  
  /** --- tasks ---- */
  public int addTaskForSystem(byte[] file, String desc) throws IOException;

  public EvTaskInfo getTaskForSystem(int id) throws IOException;

  public void deleteTaskFromSystem(int id) throws IOException;

  public Integer[] getTaskIDsForSystem() throws IOException;

  public void changeTaskState(int id, int state) throws IOException;
  
  
  /** ---- resources ---- */
  public boolean setResource(Object res, String name) throws IOException; 
  
  public Object getResource(String name) throws IOException; 
  
  public String[] getResourceNames() throws IOException;
  
  public boolean deleteResource(String name) throws IOException;
  
  /** ------- statistics ----- **/
  
  public Object[] getStatistics(long task_id, long cell_id, long node_id) throws IOException;
  public Object[] getStatisticsByCells(long taks_id, int[] cells);
  public Object[] getStatisticsByNodes(long taks_id, int[] nodes);
  public Object[] getStatisticsByID(long task_id);
  public void saveStatistic(long task_id, long cell_id, long node_id, Object stat, long iteration, long time)  throws IOException;
  public Long[] getTaskIdsWithStatistics() throws IOException;
  public Long[] getCellIdsWithStatistics(long task_id) throws IOException;
  public Long[] getNodesIdsWithStatistics(long task_id, long cell_id) throws IOException;
  public void deleteStatisticForTask(long task_id) throws IOException;
  
}